<template>
  <el-card shadow="never">
    <template #header>
      <shortcut-key />
    </template>
    <div class="flex flex-column align-center">
      <div class="preview-head">
        <div class="preview-header-title pointer" ref="inputWrapper">
          <el-input
            ref="inputTitle"
            v-if="isOutside"
            class="title-input"
            v-model.trim="titleValue"
            maxlength="50"
            placeholder="请输入标题"
          >
          </el-input>
          <span v-else>{{ titleValue }}</span>
        </div>
      </div>
      <div
        class="preview-viewport"
        @click="setActive('page')"
        :class="{ active: currentId === 'page' }"
      >
        <div
          id="preview-wrapper"
          class="preview-wrapper"
          :class="{ 'canvas-fix': canvasFix }"
          :style="getPageStyle"
        >
          <edit-wrapper
            :id="item.id"
            :props="item.props"
            v-for="item in components"
            :key="item.id"
            :class="{ active: item.id === currentId && !item.isHidden }"
            class="preview-item"
            @updatePosition="changeProps"
            @click.stop="setActive(item.id)"
            :data-id="item.id"
          >
            <component
              :data-id="item.id"
              v-if="!item.isHidden"
              :is="item.name"
              v-bind="item.props"
              :isEditing="true"
            />
          </edit-wrapper>
        </div>
      </div>
    </div>
    <context-menu @onSelecte="setActive" />
  </el-card>
</template>

<script lang="ts">
import { defineComponent, computed, watch, ref, nextTick } from "vue";
import { useStore } from "vuex";
import { IGlobalDataProps } from "@/store/index.ts";
import { initHotKeys } from "@/plugins/hotKeys.ts";

import {
  UPDATE_CURRENT_ID,
  UPDATE_COMPONENT_PROPS,
  UPDATE_PAGE_PROPS,
  UPDATE_PAGE,
} from "@/utils/Const";
import EditWrapper from "@/components/EditWrapper/index.vue";
import ShortcutKey from "@/components/ShortcutKey/index.vue";
import ContextMenu from "@/components/ContextMenu/index.vue";
import { cloneDeep } from "lodash-es";
import useClickOutside from "@/hooks/useClickOutside";
import useAppInstance from "@/hooks/useAppInstance";
export default defineComponent({
  name: "EditorCenter",
  components: {
    EditWrapper,
    ShortcutKey,
    ContextMenu,
  },
  setup(props) {
    const store = useStore<IGlobalDataProps>();
    const { globalFunc } = useAppInstance();
    let inputWrapper = ref<null | HTMLElement>(null);
    let inputTitle = ref<null | HTMLElement>(null);
    let components = computed(() => store.state.editor.components);
    let currentId = computed(() => store.state.editor.currentId);
    let pageData = computed(() => store.state.editor.page);
    let canvasFix = computed(() => store.state.editor.canvasFix);
    let titleValue = ref<string>(pageData.value.title);
    let getPageStyle = computed(() => {
      let styles = cloneDeep(pageData.value.props);
      styles["backgroundImage"] = `url(${styles["backgroundImage"]})`;
      return styles;
    });

    // 更新属性
    const changeProps = (v: any) => {
      store.commit(`editor/${UPDATE_COMPONENT_PROPS}`, v);
    };

    // 更新选中的组件ID
    let setActive = (id: string): void => {
      store.commit(`editor/${UPDATE_CURRENT_ID}`, id);
    };

    // 快捷键
    initHotKeys();

    // 是否点击
    let isOutside = useClickOutside(inputWrapper);
    watch(isOutside, async (newValue: any) => {
      if (newValue) {
        await nextTick();
        if (inputTitle.value) {
          inputTitle.value.focus();
        }
      } else {
        if (!titleValue.value) {
          globalFunc.$message.warning({
            message: "标题不能为空",
            type: "warning",
          });
          titleValue.value = pageData.value.title;
          return;
        }
        store.commit(`editor/${UPDATE_PAGE}`, {
          key: "title",
          v: titleValue.value,
        });
      }
    });

    return {
      components,
      currentId,
      setActive,
      pageData,
      titleValue,
      getPageStyle,
      changeProps,
      inputWrapper,
      inputTitle,
      isOutside,
      canvasFix,
    };
  },
});
</script>

<style lang="scss" scoped>
.preview-head {
  width: 375px;
  height: 64px;
  position: relative;
  background: url("~@/assets/images/mobile-stsbar.png") no-repeat;
  background-size: cover;
  box-shadow: 0 0 14px 0 rgb(0 0 0 / 10%);
}

.preview-header-title {
  position: absolute;
  text-align: center;
  left: 50%;
  transform: translateX(-50%);
  bottom: 10px;
}
.preview-viewport {
  width: 375px;
  max-height: 667px;
  overflow-y: scroll;
  border: 1px solid #efefef;
}
.preview-wrapper {
  position: relative;
  width: 375px;
  height: 667px;
  box-sizing: border-box;
  overflow-x: hidden;
  overflow-y: auto;
}
.preview-item {
  position: absolute !important;
  border: 1px dashed transparent !important;
  /* 同步外部大小 */
  .h-text,
  .h-image,
  .h-shape {
    width: 100% !important;
    height: 100% !important;
  }
}
.preview-wrapper.canvas-fix {
  .h-text,
  .h-image,
  .h-shape {
    box-shadow: none !important;
  }
}

.preview-item:hover {
  border: 1px dashed #f60 !important;
}
.preview-item.active {
  border: 1px solid #f60 !important;
}
.active {
  border: 1px solid #f60 !important;
}
</style>
<style lang="scss">
.title-input {
  height: 30px;
  .el-input__inner {
    height: 30px;
  }
}
</style>
